package com.xzz.mybatis.generator.utils;

import com.google.common.collect.Sets;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;

import java.util.Collection;
import java.util.Map;

/**
 * 获取spring 上下文
 *
 * @author 朱智贤
 * @since 2019-08-13
 */
@Slf4j
@Component
public class MyApplicationContextUtil implements ApplicationContextAware {

    private static ApplicationContext applicationContext;

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) {
        staticInit(applicationContext);
    }

    /**解决 sonar Instance methods should not write to "static" fields
     * 虽然实例方法最好不要修改静态变量，但是这个地方只会被初始化一次，还是比较安全 */
    private static void staticInit(ApplicationContext appCtx){
        applicationContext = appCtx;
    }

    public static ApplicationContext getApplicationContext(){
        return applicationContext;
    }

    /**根据class获取bean*/
    public static <T> T getBean(Class<T> tClass){
        return applicationContext.getBean(tClass);
    }

    /**根据beanName获取bean*/
    public static <T> T getBean(Class<T> tClass, String beanName){
        Object bean = applicationContext.getBean(beanName);
        try {
            if (tClass.isAssignableFrom(MyAopTargetUtils.getTarget(bean).getClass())) {
                return (T) bean;
            }
        }catch (Exception e){
            log.warn(beanName+" is not exist or Class type is not right");
        }
        return null;
    }

    /**根据beanName获取bean*/
    public static Object getBeanByName(String beanName){
        return applicationContext.getBean(beanName);
    }

    /**根据class获取多个实现类的bean*/
    public static <T> Collection<T> getBeansOfType(Class<T> tClass){
        Map<String, T> beanMap = applicationContext.getBeansOfType(tClass);
        return beanMap.isEmpty() ? Sets.newHashSet() : beanMap.values();
    }
}
